home *** CD-ROM | disk | FTP | other *** search
/ LiquidLibrary 2005 February / LiquidLibrary 2005 February - Disc 1.iso / pc / Portfolio Browser / Filters / PDF / LIB / gs_res.ps < prev    next >
Text File  |  2003-01-03  |  29KB  |  918 lines

  1. %    Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This software is licensed to a single customer by Artifex Software Inc.
  3. % under the terms of a specific OEM agreement.
  4.  
  5. % $RCSfile$ $Revision$
  6. % Initialization file for Level 2 resource machinery.
  7. % When this is run, systemdict is still writable,
  8. % but (almost) everything defined here goes into level2dict.
  9.  
  10. level2dict begin
  11.  
  12. (BEGIN RESOURCES) VMDEBUG
  13.  
  14. % We keep track of (global) instances with another entry in the resource
  15. % dictionary, an .Instances dictionary.  For categories with implicit
  16. % instances, the values in .Instances are the same as the keys;
  17. % for other categories, the values are [instance status size].
  18.  
  19. % Note that the dictionary that defines a resource category is stored
  20. % in global VM.  The PostScript manual says that each category must
  21. % manage global and local instances separately.  However, objects in
  22. % global VM other than systemdict can't reference objects in local VM.
  23. % This means that the resource category dictionary, which would otherwise be
  24. % the obvious place to keep track of the instances, can't be used to keep
  25. % track of local instances.  Instead, we define a dictionary in local VM
  26. % called localinstancedict, in which the key is the category name and
  27. % the value is the analogue of .Instances for local instances.
  28.  
  29. % We don't currently implement automatic resource unloading.
  30. % When and if we do, it should be hooked to the garbage collector.
  31. % However, Ed Taft of Adobe says their interpreters don't implement this
  32. % either, so we aren't going to worry about it for a while.
  33.  
  34. currentglobal false setglobal systemdict begin
  35.   /localinstancedict 5 dict
  36.   .forcedef    % localinstancedict is local, systemdict is global
  37. end true setglobal
  38. /.emptydict 0 dict readonly def
  39. setglobal
  40.  
  41. % Resource category dictionaries have the following keys (those marked with
  42. % * are optional):
  43. %    Standard, defined in the Red Book:
  44. %        Category (name)
  45. %        *InstanceType (name)
  46. %        DefineResource
  47. %            <key> <instance> DefineResource <instance>
  48. %        UndefineResource
  49. %            <key> UndefineResource -
  50. %        FindResource
  51. %            <key> FindResource <instance>
  52. %        ResourceStatus
  53. %            <key> ResourceStatus <status> <size> true
  54. %            <key> ResourceStatus false
  55. %        ResourceForAll
  56. %            <template> <proc> <scratch> ResourceForAll -
  57. %        *ResourceFileName
  58. %            <key> <scratch> ResourceFileName <filename>
  59. %    Additional, specific to our implementation:
  60. %        .Instances (dictionary)
  61. %        .LocalInstances
  62. %            - .LocalInstances <dict>
  63. %        .GetInstance
  64. %            <key> .GetInstance <instance> -true-
  65. %            <key> .GetInstance -false-
  66. %        .CheckResource
  67. %            <key> <value> .CheckResource <key> <value> <ok>
  68. %              (or may give an error if not OK)
  69. %        .DoLoadResource
  70. %            <key> .DoLoadResource <key> (may give an error)
  71. %        .LoadResource
  72. %            <key> .LoadResource - (may give an error)
  73. %        .ResourceFile
  74. %            <key> .ResourceFile <file> -true-
  75. %            <key> .ResourceFile <key> -false-
  76. %        .ResourceFileStatus
  77. %            <key> .ResourceFileStatus 2 <vmusage> -true-
  78. %            <key> .ResourceFileStatus -false-
  79. % All the above procedures expect that the top dictionary on the d-stack
  80. % is the resource dictionary.
  81.  
  82. % Define enough of the Category category so we can define other categories.
  83. % The dictionary we're about to create will become the Category
  84. % category definition dictionary.
  85.  
  86. % .findcategory and .resourceexec are only called from within the
  87. % implementation of the resource 'operators', so they doesn't have to worry
  88. % about cleaning up the stack if they fail (the interpreter's stack
  89. % protection machinery for pseudo-operators takes care of this).
  90. /.findcategory {    % <name> .findcategory -
  91.             %   (pushes the category on the dstack)
  92.   /Category findresource begin
  93. } bind def
  94.  
  95. /.resourceexec {    % <key> /xxxResource .resourceexec -
  96.             %   (also pops the category from the dstack)
  97.   load exec end
  98. } bind def
  99.  
  100. % .getvminstance treats instances on disk as undefined.
  101. /.getvminstance {    % <key> .getvminstance <instance> -true-
  102.             % <key> .getvminstance -false-
  103.   .GetInstance {
  104.     dup 1 get 2 ne { true } { pop false } ifelse
  105.   } {
  106.     false
  107.   } ifelse
  108. } bind def
  109.  
  110. 20 dict begin
  111.  
  112.         % Standard entries
  113.  
  114. /Category /Category def
  115. /InstanceType /dicttype def
  116.  
  117. /DefineResource {
  118.     .CheckResource {
  119.       dup /Category 3 index cvlit .growput
  120.       dup [ exch 0 -1 ] exch
  121.       .Instances 4 2 roll put
  122.         % Make the Category dictionary read-only.  We will have to
  123.         % use .forceput / .forcedef later to replace the dummy,
  124.         % empty .Instances dictionary with the real one later.
  125.       readonly
  126.     } {
  127.       /defineresource load /typecheck signalerror
  128.     } ifelse
  129. } bind def
  130. /FindResource        % (redefined below)
  131.     { .Instances exch get 0 get
  132.     } bind def
  133.  
  134.         % Additional entries
  135.  
  136. /.Instances 30 dict def
  137. .Instances /Category [currentdict 0 -1] put
  138.  
  139. /.LocalInstances 0 dict def
  140. /.GetInstance
  141.     { .Instances exch .knownget
  142.     } bind def
  143. /.CheckResource
  144.     { dup gcheck currentglobal and
  145.        { /DefineResource /FindResource /ResourceForAll /ResourceStatus
  146.          /UndefineResource }
  147.        { 2 index exch known and }
  148.       forall
  149.       not { /defineresource load /invalidaccess signalerror } if
  150.       true
  151.     } bind def
  152.  
  153. .Instances end begin    % for the base case of findresource
  154.  
  155. (END CATEGORY) VMDEBUG
  156.  
  157. % Define the resource operators.  We use the "stack protection" feature of
  158. % odef to make sure the stacks are restored properly on an error.
  159. % This requires that the operators not pop anything from the stack until
  160. % they have executed their logic successfully.  We can't make this
  161. % work for resourceforall, because the procedure it executes mustn't see
  162. % the operands of resourceforall on the stack, but we can make it work for
  163. % the others.
  164.  
  165. % findresource is the only operator that needs to bind //Category.
  166. /findresource {        % <key> <category> findresource <instance>
  167.     2 copy dup /Category eq
  168.       { pop //Category 0 get begin } { .findcategory } ifelse
  169.     /FindResource .resourceexec exch pop exch pop
  170. } bind
  171. end        % .Instances of Category
  172. odef
  173.  
  174. /defineresource {    % <key> <instance> <category> defineresource <instance>
  175.     3 copy .findcategory
  176.     currentdict /InstanceType known {
  177.       dup type InstanceType ne {
  178.         dup type /packedarraytype eq InstanceType /arraytype eq and
  179.         not { /defineresource load /typecheck signalerror } if
  180.       } if
  181.     } if
  182.     /DefineResource .resourceexec
  183.     4 1 roll pop pop pop
  184. } bind odef
  185. % We must prevent resourceforall from automatically restoring the stacks,
  186. % because we don't want the stacks restored if proc causes an error.
  187. % On the other hand, resourceforall is defined in the PLRM as an operator,
  188. % so it must have type /operatortype.  We hack this by taking advantage of
  189. % the fact that the interpreter optimizes tail calls, so stack protection
  190. % doesn't apply to the very last token of an operator procedure.
  191. /resourceforall1 {    % <template> <proc> <scratch> <category> resourceforall1 -
  192.     dup /Category findresource begin
  193.     /ResourceForAll load
  194.         % Make sure we can recover the original operands.
  195.         % We must create the array in local VM, in case any of the
  196.         % operands are local.
  197.         % Stack: ...operands... proc
  198.     5 copy pop .currentglobal false .setglobal 5 1 roll
  199.     4 packedarray exch .setglobal count
  200.         % Stack: ...operands... proc saved count
  201.     4 -1 roll pop        % pop the category
  202.     /stopped load 3 1 roll
  203.     3 .execn
  204.         % Stack: ... stopped saved count
  205.     3 -1 roll {
  206.       .currentstackprotect {
  207.         % The count is the original stack depth + 2.
  208.         count exch 4 sub sub { exch pop } repeat
  209.         aload pop end
  210.       } {
  211.         % Don't restore the stacks.
  212.         pop pop
  213.       } ifelse stop
  214.     } {
  215.       pop pop end
  216.     } ifelse
  217. } bind def
  218. /resourceforall {    % <template> <proc> <scratch> <category> resourceforall1 -
  219.     //resourceforall1 exec        % see above
  220. } bind odef
  221. /resourcestatus {    % <key> <category> resourcestatus <status> <size> true
  222.             % <key> <category> resourcestatus false
  223.     2 copy .findcategory /ResourceStatus .resourceexec
  224.      { 4 2 roll pop pop true } { pop pop false } ifelse
  225. } bind odef
  226. /undefineresource {    % <key> <category> undefineresource -
  227.     2 copy .findcategory /UndefineResource .resourceexec pop pop
  228. } bind odef
  229.  
  230. % Define the system parameters used for the Generic implementation of
  231. % ResourceFileName.
  232. systemdict begin
  233. currentdict /pssystemparams known not {
  234.   /pssystemparams 10 dict readonly def
  235. } if
  236. pssystemparams begin
  237.   /FontResourceDir (/Resource/Font/) readonly .forcedef    % pssys'params is r-o
  238.   /GenericResourceDir (/Resource/) readonly .forcedef    % pssys'params is r-o
  239.   /GenericResourcePathSep (/) readonly .forcedef    % pssys'params is r-o
  240. end
  241. end
  242.  
  243. % Define the generic algorithm for computing resource file names.
  244. /.rfnstring 100 string def
  245. /.genericrfn        % <key> <scratch> <prefix> .genericrfn <filename>
  246.  { 3 -1 roll //.rfnstring cvs concatstrings exch copy
  247.  } bind def
  248.  
  249. % Define a procedure for making a packed array in local VM.
  250. /.localpackedarray {    % <obj1> ... <objn> <n> .localpackedarray <packedarray>
  251.   .currentglobal false .setglobal 1 index 2 add 1 roll
  252.   packedarray exch .setglobal
  253. } bind def
  254.  
  255. % Define the Generic category.
  256.  
  257. /Generic mark
  258.  
  259.         % Standard entries
  260.  
  261. % We're still running in Level 1 mode, so dictionaries won't expand.
  262. % Leave room for the /Category entry.
  263. /Category null
  264.  
  265. % Implement the body of Generic resourceforall for local, global, and
  266. % external cases.  'args' is [template proc scratch resdict].
  267. /.enumerateresource {    % <key> [- <proc> <scratch>] .enumerateresource -
  268.   1 index type dup /stringtype eq exch /nametype eq or {
  269.     exch 1 index 2 get cvs exch
  270.   } if
  271.     % Use .setstackprotect to prevent the stacks from being restored if
  272.     % an error occurs during execution of proc.
  273.   1 get false .setstackprotect exec true .setstackprotect
  274. } bind def
  275. /.localresourceforall {        % <key> <value> <args> .localr'forall -
  276.   exch pop
  277.   2 copy 0 get .stringmatch { .enumerateresource } { pop pop } ifelse
  278. } bind def
  279. /.globalresourceforall {    % <key> <value> <args> .globalr'forall -
  280.   exch pop
  281.   2 copy 0 get .stringmatch {
  282.     dup 3 get begin .LocalInstances end 2 index known not {
  283.       .enumerateresource
  284.     } if
  285.   } {
  286.     pop pop
  287.   } ifelse
  288. } bind def
  289. /.externalresourceforall {    % <filename> <len> <args> .externalr'forall -
  290.   3 1 roll 1 index length 1 index sub getinterval exch
  291.   dup 3 get begin .Instances .LocalInstances end
  292.         % Stack: key args insts localinsts
  293.   3 index known {
  294.     pop pop pop
  295.   } {
  296.     2 index known { pop pop } { .enumerateresource } ifelse
  297.   } ifelse
  298. } bind def
  299.  
  300. /DefineResource {
  301.     .CheckResource
  302.        { dup [ exch 0 -1 ]
  303.             % Stack: key value instance
  304.          currentglobal
  305.           { false setglobal 2 index UndefineResource    % remove local def if any
  306.         true setglobal
  307.         .Instances dup //.emptydict eq {
  308.           pop 3 dict
  309.             % As noted above, Category dictionaries are read-only,
  310.             % so we have to use .forcedef here.
  311.           /.Instances 1 index .forcedef    % Category dict is read-only
  312.         } if
  313.           }
  314.           { .LocalInstances dup //.emptydict eq
  315.              { pop 3 dict localinstancedict Category 2 index put
  316.          }
  317.         if
  318.           }
  319.          ifelse
  320.             % Stack: key value instance instancedict
  321.          3 index 2 index .growput
  322.             % Now make the resource value read-only.
  323.          0 2 copy get { readonly } .internalstopped pop
  324.          dup 4 1 roll put exch pop exch pop
  325.        }
  326.        { /defineresource load /typecheck signalerror
  327.        }
  328.     ifelse
  329. } bind executeonly        % executeonly to prevent access to .forcedef
  330. /UndefineResource
  331.     {  { dup 2 index .knownget
  332.           { dup 1 get 1 ge
  333.          { dup 0 null put 1 2 put pop pop }
  334.          { pop exch .undef }
  335.         ifelse
  336.           }
  337.           { pop pop
  338.           }
  339.          ifelse
  340.        }
  341.       currentglobal
  342.        { 2 copy .Instances exch exec
  343.        }
  344.       if .LocalInstances exch exec
  345.     } bind
  346. % Because of some badly designed code in Adobe's CID font downloader that
  347. % makes findresource and resourcestatus deliberately inconsistent with each
  348. % other, the default FindResource must not call ResourceStatus if there is
  349. % an instance of the desired name already defined in VM.
  350. /FindResource {
  351.     dup .getvminstance {
  352.       exch pop 0 get
  353.     } {
  354.       dup ResourceStatus {
  355.         pop 1 gt {
  356.           .DoLoadResource .getvminstance not {
  357.         /findresource load /undefinedresource signalerror
  358.           } if 0 get
  359.         } {
  360.           .GetInstance pop 0 get
  361.         } ifelse
  362.       } {
  363.        /findresource load /undefinedresource signalerror
  364.       } ifelse
  365.     } ifelse
  366. } bind
  367. % Because of some badly designed code in Adobe's CID font downloader, the
  368. % definition of ResourceStatus for Generic and Font must be the same (!).
  369. % We patch around this by using an intermediate .ResourceFileStatus procedure.
  370. /ResourceStatus {
  371.     dup .GetInstance {
  372.       exch pop dup 1 get exch 2 get true
  373.     } {
  374.       .ResourceFileStatus
  375.     } ifelse
  376. } bind
  377. /.ResourceFileStatus {
  378.     .ResourceFile { closefile 2 -1 true } { pop false } ifelse
  379. } bind
  380. /ResourceForAll {
  381.         % **************** Doesn't present instance groups in
  382.         % **************** the correct order yet.
  383.         % Construct a new procedure to hold the arguments.
  384.         % All objects constructed here must be in local VM to avoid
  385.         % a possible invalidaccess.
  386.     currentdict 4 .localpackedarray    % [template proc scratch resdict]
  387.         % We must pop the resource dictionary off the dict stack
  388.         % when doing the actual iteration, and restore it afterwards.
  389.     .currentglobal not {
  390.       .LocalInstances length 0 ne {
  391.         % We must do local instances, and do them first.
  392.         //.localresourceforall {exec} 0 get 3 .localpackedarray cvx
  393.         .LocalInstances exch {forall} 0 get 1 index 0 get
  394.         currentdict end 3 .execn begin
  395.       } if
  396.     } if
  397.         % Do global instances next.
  398.     //.globalresourceforall {exec} 0 get 3 .localpackedarray cvx
  399.     .Instances exch cvx {forall} 0 get 1 index 0 get
  400.     currentdict end 3 .execn begin
  401.     currentdict /ResourceFileName known {
  402.         % Finally, do instances stored on files.
  403.       dup 0 get 100 string ResourceFileName
  404.       dup length 2 index 0 get length sub 3 -1 roll
  405.       //.externalresourceforall {exec} 0 get 4 .localpackedarray cvx
  406.       100 string {filenameforall} 0 get
  407.       currentdict end 2 .execn begin null    % for pop
  408.     } if pop
  409. } bind
  410. /ResourceFileName
  411.     { /GenericResourceDir getsystemparam 
  412.       Category .namestring concatstrings
  413.       /GenericResourcePathSep getsystemparam concatstrings
  414.       .genericrfn
  415.     } bind
  416.  
  417.         % Additional entries
  418.  
  419. % Unfortunately, we can't create the real .Instances dictionary now,
  420. % because if someone copies the Generic category (which pp. 95-96 of the
  421. % 2nd Edition Red Book says is legitimate), they'll wind up sharing
  422. % the .Instances.  Instead, we have to create .Instances on demand,
  423. % just like the entry in localinstancedict.
  424. % We also have to prevent anyone from creating instances of Generic itself.
  425. /.Instances //.emptydict
  426.  
  427. /.LocalInstances
  428.     { localinstancedict Category .knownget not { //.emptydict } if
  429.     } bind
  430. /.GetInstance
  431.     { currentglobal
  432.        { .Instances exch .knownget }
  433.        { .LocalInstances 1 index .knownget
  434.           { exch pop true }
  435.           { .Instances exch .knownget }
  436.          ifelse
  437.        }
  438.       ifelse
  439.     } bind
  440. /.CheckResource
  441.     { true
  442.     } bind
  443. /.vmused {
  444.         % - .vmused <usedvalue>
  445.         % usedvalue = vmstatus in global + vmstatus in local.
  446.   0 2 {
  447.     .currentglobal not .setglobal
  448.     vmstatus pop exch pop add
  449.   } repeat
  450. } bind def
  451. /.DoLoadResource {
  452.         % .LoadResource may push entries on the operand stack.
  453.         % It is an undocumented feature of Adobe implementations,
  454.         % which we must match for the sake of some badly written
  455.         % font downloading code, that such entries are popped
  456.         % automatically.
  457.     count 1 index cvlit .vmused
  458.         % Stack: key count litkey memused
  459.     {.LoadResource} 4 1 roll 4 .execn
  460.         % Stack: ... count key memused
  461.     .vmused exch sub
  462.     1 index .getvminstance not {
  463.       pop dup /undefinedresource signalerror    % didn't load
  464.     } if
  465.     dup 1 1 put
  466.     2 3 -1 roll put
  467.         % Stack: ... count key
  468.     exch count 1 sub exch sub {exch pop} repeat
  469. } bind
  470. /.LoadResource
  471.     { dup .ResourceFile
  472.        { exch pop currentglobal
  473.           { .runresource }
  474.           { true setglobal { .runresource } stopped false setglobal { stop } if }
  475.          ifelse
  476.        }
  477.        { dup /undefinedresource signalerror
  478.        }
  479.      ifelse
  480.     } bind
  481. /.ResourceFile
  482.     { currentdict /ResourceFileName known
  483.        { mark 1 index 100 string { ResourceFileName }
  484.          .internalstopped
  485.           { cleartomark false }
  486.           { exch pop findlibfile
  487.          { exch pop exch pop true }
  488.          { pop false }
  489.         ifelse
  490.           }
  491.          ifelse
  492.        }
  493.        { false }
  494.       ifelse
  495.     } bind
  496.  
  497. .dicttomark
  498. /Category defineresource pop
  499.  
  500. % Fill in the rest of the Category category.
  501. /Category /Category findresource dup
  502. /Generic /Category findresource begin {
  503.   /FindResource /ResourceForAll /ResourceStatus /.ResourceFileStatus
  504.   /UndefineResource /ResourceFileName
  505.   /.ResourceFile /.LoadResource /.DoLoadResource
  506. } { dup load put dup } forall
  507. pop readonly pop end
  508.  
  509. (END GENERIC) VMDEBUG
  510.  
  511. % Define the fixed categories.
  512.  
  513. mark
  514.     % Non-Type categories with existing entries.
  515.  /ColorSpaceFamily
  516.    { }    % These must be deferred, because optional features may add some.
  517.  /Emulator
  518.    mark EMULATORS { cvn } forall .packtomark
  519.  /Filter
  520.    { }    % These must be deferred, because optional features may add some.
  521.  /IODevice
  522.     % Loop until the .getiodevice gets a rangecheck.
  523.    errordict /rangecheck 2 copy get
  524.    errordict /rangecheck { pop stop } put    % pop the command
  525.    mark 0 { {
  526.     dup .getiodevice dup null eq { pop } { exch } ifelse 1 add
  527.    } loop} .internalstopped
  528.    pop pop pop .packtomark
  529.    4 1 roll put
  530.    .clearerror
  531.     % Type categories listed in the Red Book.
  532.  /ColorRenderingType
  533.    { }    % These must be deferred, because optional features may add some.
  534.  /FMapType
  535.    { }    % These must be deferred, because optional features may add some.
  536.  /FontType
  537.    { }    % These must be deferred, because optional features may add some.
  538.  /FormType
  539.    { }    % These must be deferred, because optional features may add some.
  540.  /HalftoneType
  541.    { }    % These must be deferred, because optional features may add some.
  542.  /ImageType
  543.    { }    % Deferred, optional features may add some.
  544.  /PatternType
  545.    { }  % Deferred, optional features may add some.
  546.     % Type categories added since the Red Book.
  547.  /setsmoothness where {
  548.    pop /ShadingType { }    % Deferred, optional features may add some.
  549.  } if
  550. counttomark 2 idiv
  551.  { mark
  552.  
  553.         % Standard entries
  554.  
  555.         % We'd like to prohibit defineresource,
  556.         % but because optional features may add entries, we can't.
  557.         % We can at least require that the key and value match.
  558.    /DefineResource
  559.     { currentglobal not
  560.        { /defineresource load /invalidaccess signalerror }
  561.        { 2 copy ne
  562.           { /defineresource load /rangecheck signalerror }
  563.           { dup .Instances 4 -2 roll .growput }
  564.          ifelse
  565.        }
  566.       ifelse
  567.     } bind
  568.    /UndefineResource
  569.     { /undefineresource load /invalidaccess signalerror } bind
  570.    /FindResource
  571.     { .Instances 1 index .knownget
  572.        { exch pop }
  573.        { /findresource load /undefinedresource signalerror }
  574.       ifelse
  575.     } bind
  576.    /ResourceStatus
  577.     { .Instances exch known { 0 0 true } { false } ifelse } bind
  578.    /ResourceForAll
  579.     /Generic /Category findresource /ResourceForAll get
  580.  
  581.         % Additional entries
  582.  
  583.    counttomark 2 add -1 roll
  584.    dup length dict dup begin exch { dup def } forall end
  585.         % We'd like to make the .Instances readonly here,
  586.         % but because optional features may add entries, we can't.
  587.    /.Instances exch
  588.    /.LocalInstances    % used by ResourceForAll
  589.     0 dict def
  590.  
  591.    .dicttomark /Category defineresource pop
  592.  } repeat pop
  593.  
  594. (END FIXED) VMDEBUG
  595.  
  596. % Define the other built-in categories.
  597.  
  598. /.definecategory    % <name> -mark- <key1> ... <valuen> .definecategory -
  599.  { counttomark 2 idiv 2 add        % .Instances, Category
  600.    /Generic /Category findresource dup maxlength 3 -1 roll add
  601.    dict .copydict begin
  602.    counttomark 2 idiv { def } repeat pop    % pop the mark
  603.    currentdict end /Category defineresource pop
  604.  } bind def
  605.  
  606. /ColorRendering mark /InstanceType /dicttype .definecategory
  607. % ColorSpace is defined below
  608. % Encoding is defined below
  609. % Font is defined below
  610. /Form mark /InstanceType /dicttype .definecategory
  611. /Halftone mark /InstanceType /dicttype .definecategory
  612. /Pattern mark /InstanceType /dicttype .definecategory
  613. /ProcSet mark /InstanceType /dicttype .definecategory
  614. % Added since the Red Book:
  615. /ControlLanguage mark /InstanceType /dicttype .definecategory
  616. /HWOptions mark /InstanceType /dicttype .definecategory
  617. /Localization mark /InstanceType /dicttype .definecategory
  618. /OutputDevice mark /InstanceType /dicttype .definecategory
  619. /PDL mark /InstanceType /dicttype .definecategory
  620. % CIDFont, CIDMap, and CMap are defined in gs_cidfn.ps
  621. % FontSet is defined in gs_cff.ps
  622. % IdiomSet is defined in gs_ll3.ps
  623. % InkParams and TrapParams are defined in gs_trap.ps
  624.  
  625. (END MISC) VMDEBUG
  626.  
  627. % Define the ColorSpace category.
  628.  
  629. /.defaultcsnames mark
  630.   /DefaultGray 0
  631.   /DefaultRGB 1
  632.   /DefaultCMYK 2
  633. .dicttomark readonly def
  634.  
  635. % The "hooks" are no-ops here, redefined in LL3.
  636. /.definedefaultcs {    % <index> <value> .definedefaultcs -
  637.   pop pop
  638. } bind def
  639. /.undefinedefaultcs {    % <index> .undefinedefaultcs -
  640.   pop
  641. } bind def
  642.  
  643. /ColorSpace mark
  644.  
  645. /InstanceType /arraytype
  646.  
  647. % We keep track of whether there are any local definitions for any of
  648. % the Default keys.  This information must get saved and restored in
  649. % parallel with the local instance dictionary, so it must be stored in
  650. % local VM.
  651. userdict /.localcsdefaults false put
  652.  
  653. /DefineResource {
  654.   2 copy /Generic /Category findresource /DefineResource get exec
  655.   exch pop
  656.   exch //.defaultcsnames exch .knownget {
  657.     1 index .definedefaultcs
  658.     currentglobal not { .userdict /.localcsdefaults true put } if
  659.   } if
  660. } bind
  661.  
  662. /UndefineResource {
  663.   dup /Generic /Category findresource /UndefineResource get exec
  664.   //.defaultcsnames 1 index .knownget {
  665.     % Stack: resname index
  666.     currentglobal {
  667.       .undefinedefaultcs pop
  668.     } {
  669.     % We removed the local definition, but there might be a global one.
  670.       exch .GetInstance {
  671.     0 get .definedefaultcs
  672.       } {
  673.     .undefinedefaultcs
  674.       } ifelse
  675.     % Recompute .localcsdefaults by scanning.  This is rarely needed.
  676.       .userdict /.localcsdefaults false //.defaultcsnames {
  677.     pop .LocalInstances exch known { pop true exit } if
  678.       } forall put
  679.     } ifelse
  680.   } {
  681.     pop
  682.   } ifelse
  683. } bind
  684.  
  685. .definecategory            % ColorSpace
  686.  
  687. % Define the Encoding category.
  688.  
  689. /Encoding mark
  690.  
  691. /InstanceType /arraytype
  692.  
  693. % Handle already-registered encodings, including lazily loaded encodings
  694. % that aren't loaded yet.
  695.  
  696. /.Instances mark
  697.   EncodingDirectory
  698.    { dup length 256 eq { [ exch readonly 0 -1 ] } { pop [null 2 -1] } ifelse
  699.    } forall
  700. .dicttomark
  701.  
  702. /.ResourceFileDict mark
  703.   EncodingDirectory
  704.    { dup length 256 eq { pop pop } { 0 get } ifelse
  705.    } forall
  706. .dicttomark
  707.  
  708. /ResourceFileName
  709.  { .ResourceFileDict 2 index .knownget
  710.     { exch copy exch pop }
  711.     { /Generic /Category findresource /ResourceFileName get exec }
  712.    ifelse
  713.  } bind
  714.  
  715. .definecategory            % Encoding
  716.  
  717. % Make placeholders in level2dict for the redefined Encoding operators,
  718. % so that they will be swapped properly when we switch language levels.
  719.  
  720. /.findencoding /.findencoding load def
  721. /findencoding /findencoding load def
  722. /.defineencoding /.defineencoding load def
  723.  
  724. (END ENCODING) VMDEBUG
  725.  
  726. % Define the Font category.
  727.  
  728. /.fontstatus {        % <fontname> .fontstatus <fontname> <found>
  729.   {        % Create a loop context just so we can exit it early.
  730.         % Check Fontmap.
  731.     Fontmap 1 index .knownget {
  732.       {
  733.     dup type /nametype eq {
  734.       .fontstatus { pop null exit } if
  735.     } {
  736.       dup type /stringtype eq {
  737.         findlibfile { closefile pop null exit } if pop
  738.       } {
  739.         % Procedure, assume success.
  740.         pop null exit
  741.       } ifelse
  742.     } ifelse
  743.       } forall dup null eq { pop true exit } if
  744.     } if
  745.         % Convert names to strings; give up on other types.
  746.     dup type /nametype eq { .namestring } if
  747.     dup type /stringtype ne { false exit } if
  748.         % Check the resource directory.
  749.     dup .fonttempstring /FontResourceDir getsystemparam .genericrfn
  750.     status {
  751.       pop pop pop pop true exit
  752.     } if
  753.         % Check for a file on the search path with the same name
  754.         % as the font.
  755.     findlibfile { closefile true exit } if
  756.         % Scan a FONTPATH directory and try again.
  757.     .scannextfontdir not { false exit } if
  758.   } loop
  759. } bind def
  760.  
  761. /Font mark
  762.  
  763. /InstanceType /dicttype
  764.  
  765. /DefineResource
  766.     { 2 copy //definefont exch pop
  767.       /Generic /Category findresource /DefineResource get exec
  768.     } bind
  769. /UndefineResource
  770.     { dup //undefinefont
  771.       /Generic /Category findresource /UndefineResource get exec
  772.     } bind
  773. /FindResource {
  774.     dup .getvminstance {
  775.       exch pop 0 get
  776.     } {
  777.       dup ResourceStatus {
  778.         pop 1 gt { .loadfontresource } { .GetInstance pop 0 get } ifelse
  779.       } {
  780.         .loadfontresource
  781.       } ifelse
  782.     } ifelse
  783. } bind
  784. /ResourceForAll {
  785.     { .scannextfontdir not { exit } if } loop
  786.     /Generic /Category findresource /ResourceForAll get exec
  787. } bind
  788. /.ResourceFileStatus {
  789.     .fontstatus { pop 2 -1 true } { pop false } ifelse
  790. } bind
  791.  
  792. /.loadfontresource {
  793.     dup vmstatus pop exch pop exch
  794.         % Hack: rebind .currentresourcefile so that all calls of
  795.         % definefont will know these are built-in fonts.
  796.     currentfile {pop //findfont exec} .execasresource  % (findfont is a procedure)
  797.     exch vmstatus pop exch pop exch sub
  798.         % stack: name font vmused
  799.         % findfont has the prerogative of not calling definefont
  800.         % in certain obscure cases of font substitution.
  801.     2 index .getvminstance {
  802.       dup 1 1 put
  803.       2 3 -1 roll put
  804.     } {
  805.       pop
  806.     } ifelse exch pop
  807. } bind
  808.  
  809. /.Instances FontDirectory length 2 mul dict
  810.  
  811. .definecategory            % Font
  812.  
  813. % Redefine font "operators".
  814. /.definefontmap
  815.  { /Font /Category findresource /.Instances get
  816.    dup 3 index known
  817.     { pop
  818.     }
  819.     { 2 index
  820.         % Make sure we create the array in global VM.
  821.       .currentglobal true .setglobal
  822.       [null 2 -1] exch .setglobal
  823.       .growput
  824.     }
  825.    ifelse
  826.    //.definefontmap exec
  827.  } bind def
  828.  
  829. % Make sure the old definitions are still in systemdict so that
  830. % they will get bound properly.
  831. systemdict begin
  832.   /.origdefinefont /definefont load def
  833.   /.origundefinefont /undefinefont load def
  834.   /.origfindfont /findfont load def
  835. end
  836. /definefont {
  837.   /Font defineresource
  838. } bind odef
  839. /undefinefont {
  840.   /Font undefineresource
  841. } bind odef
  842. % The Red Book requires that findfont be a procedure, not an operator,
  843. % but it still needs to restore the stacks reliably if it fails.
  844. /.findfontop {
  845.   /Font findresource
  846. } bind odef
  847. /findfont {
  848.   .findfontop
  849. } bind def    % Must be a procedure, not an operator
  850.  
  851. % Remove initialization utilities.
  852. currentdict /.definecategory .undef
  853. currentdict /.emptydict .undef
  854.  
  855. end                % level2dict
  856.  
  857. % Convert deferred resources after we finally switch to Level 2.
  858.  
  859. /.fixresources {
  860.     % Encoding resources
  861.   EncodingDirectory
  862.    { dup length 256 eq
  863.       { /Encoding defineresource pop }
  864.       { pop pop }
  865.      ifelse
  866.    } forall
  867.   /.findencoding { /Encoding findresource } bind def
  868.   /findencoding /.findencoding load def        % must be a procedure
  869.   /.defineencoding { /Encoding defineresource pop } bind def
  870.     % ColorRendering resources and ProcSet
  871.   systemdict /ColorRendering .knownget {
  872.     /ColorRendering exch /ProcSet defineresource pop
  873.     systemdict /ColorRendering undef
  874.     /Default currentcolorrendering /ColorRendering defineresource pop
  875.   } if
  876.     % ColorSpace resources
  877.   systemdict /CIEsRGB .knownget {
  878.     /sRGB exch /ColorSpace defineresource pop
  879.     systemdict /CIEsRGB undef
  880.   } if
  881.     % ColorSpaceFamily resources
  882.   colorspacedict { pop dup /ColorSpaceFamily defineresource pop } forall
  883.     % Filter resources
  884.   filterdict { pop dup /Filter defineresource pop } forall
  885.     % FontType and FMapType resources
  886.   buildfontdict { pop dup /FontType defineresource pop } forall
  887.   mark
  888.     buildfontdict 0 known { 2 3 4 5 6 7 8 } if
  889.     buildfontdict 9 known { 9 } if
  890.   counttomark { dup /FMapType defineresource pop } repeat pop
  891.     % FormType resources
  892.   .formtypes { pop dup /FormType defineresource pop } forall
  893.     % HalftoneType resources
  894.   .halftonetypes { pop dup /HalftoneType defineresource pop } forall
  895.     % ColorRenderingType resources
  896.   .colorrenderingtypes {pop dup /ColorRenderingType defineresource pop} forall
  897.     % ImageType resources
  898.   .imagetypes { pop dup /ImageType defineresource pop } forall
  899.     % PatternType resources
  900.   .patterntypes { pop dup /PatternType defineresource pop } forall
  901.     % Make the fixed resource categories immutable.
  902.   /.shadingtypes where {
  903.     pop .shadingtypes { pop dup /ShadingType defineresource pop } forall
  904.   } if
  905.   [ /ColorSpaceFamily /Emulator /Filter /IODevice /ColorRenderingType
  906.     /FMapType /FontType /FormType /HalftoneType /ImageType /PatternType
  907.     /.shadingtypes where { pop /ShadingType } if
  908.   ] {
  909.     /Category findresource
  910.     dup /.Instances get readonly pop
  911.     .LocalInstances readonly pop
  912.     readonly pop
  913.   } forall
  914.     % clean up
  915.   systemdict /.fixresources undef
  916. } bind def
  917.